﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Licensed MIT: http://www.opensource.org/licenses/mit-license.php

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.Mvc;

namespace DNA.Mvc.Publishing
{
    /// <summary>
    /// Present the decorator for Category to add methods and properties to category
    /// </summary>
    public class CategoryWrapper : Category, IHierarchicalEnumerable, IHierarchyData
    {
        private Category innerCategory;

        public CategoryWrapper(Category category)
        {
            innerCategory = category;
        }

        #region Category properties

        public override bool AllowAnonymousPostComment
        {
            get
            {
                return innerCategory.AllowAnonymousPostComment;
            }
            set
            {
                innerCategory.AllowAnonymousPostComment = value;
            }
        }

        public override ICollection<Article> Articles
        {
            get
            {
                return innerCategory.Articles;
            }
            set
            {
                innerCategory.Articles = value;
            }
        }

        public override int? ArticleType
        {
            get
            {
                return innerCategory.ArticleType;
            }
            set
            {
                innerCategory.ArticleType = value;
            }
        }

        public override string Description
        {
            get
            {
                return innerCategory.Description;
            }
            set
            {
                innerCategory.Description = value;
            }
        }

        public override bool EnableVersioning
        {
            get
            {
                return innerCategory.EnableVersioning;
            }
            set
            {
                innerCategory.EnableVersioning = value;
            }
        }

        public override int ID
        {
            get
            {
                return innerCategory.ID;
            }
            set
            {
                innerCategory.ID = value;
            }
        }

        public override bool IsModerated
        {
            get
            {
                return innerCategory.IsModerated;
            }
            set
            {
                innerCategory.IsModerated = value;
            }
        }

        public override DateTime LastPosted
        {
            get
            {
                return innerCategory.LastPosted;
            }
            set
            {
                innerCategory.LastPosted = value;
            }
        }

        public override int ParentID
        {
            get
            {
                return innerCategory.ParentID;
            }
            set
            {
                innerCategory.ParentID = value;
            }
        }

        public override string Path
        {
            get
            {
                return innerCategory.Path;
            }
            set
            {
                innerCategory.Path = value;
            }
        }

        public override int Pos
        {
            get
            {
                return innerCategory.Pos;
            }
            set
            {
                innerCategory.Pos = value;
            }
        }

        public override string Title
        {
            get
            {
                return innerCategory.Title;
            }
            set
            {
                innerCategory.Title = value;
            }
        }

        public override int TotalPosts
        {
            get
            {
                return innerCategory.TotalPosts;
            }
            set
            {
                innerCategory.TotalPosts = value;
            }
        }

        public override string ImageUrl
        {
            get
            {
                return innerCategory.ImageUrl;
            }
            set
            {
                innerCategory.ImageUrl = value;
            }
        }

        public override string Url
        {
            get
            {
                return innerCategory.Url;
            }
            set
            {
                innerCategory.Url = value;
            }
        }

        #endregion

        public string PermaLink
        {
            get
            {
                string appPath = UrlResolver.ApplicationPath + "/publishing";
                string url = Path;
                string[] parts = url.Split('/');
                url = appPath + "/" + parts[0] + "/category";
                if (parts.Length > 1)
                {
                    for (int i = 1; i < parts.Length; i++)
                        url = url + "/" + parts[i];
                }
                return url;
            }
        }

        public string RssUrl
        {
            get
            {
                return "";
                //throw new NotImplementedException();
            }
        }

        #region Implement IHierarchyData

        private IPubContext srv;

        private IPubContext Service
        {
            get
            {
                if (srv == null)
                    srv = DependencyResolver.Current.GetService<IPubContext>();
                return srv;
            }
        }

        IHierarchicalEnumerable IHierarchyData.GetChildren()
        {
            return this;
        }

        private CategoryWrapper _parent = null;

        IHierarchyData IHierarchyData.GetParent()
        {
            if ((_parent == null) && ParentID > 0)
                _parent = new CategoryWrapper(Service.Categories.Find(ParentID));
            return _parent;
        }

        private bool? _hasChildren = null;

        bool IHierarchyData.HasChildren
        {
            get
            {
                if (!_hasChildren.HasValue)
                    _hasChildren = Service.Categories.GetChildrenCount(this.ID) > 0;
                return _hasChildren.Value;
            }
        }

        object IHierarchyData.Item
        {
            get { return this; }
        }

        string IHierarchyData.Path
        {
            get { return this.Path; }
        }

        string IHierarchyData.Type
        {
            get { return this.GetType().ToString(); }
        }

        #endregion

        #region Implement IHierarchicalEnumerable

        IHierarchyData IHierarchicalEnumerable.GetHierarchyData(object enumeratedItem)
        {
            return (CategoryWrapper)enumeratedItem;
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            var children = Service.Categories.Children(this.ID).ToList().Select(c => new CategoryWrapper(c));

            if (children != null)
                return children.GetEnumerator();
            return null;
        }

        #endregion
    }
}
